package com.ny.mingli_measurement.utils;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lpyのPC
 * @date 2021/5/8
 */
public class DateFormatUtil {

    /**
     * 将用户输入的生辰日期格式化为干支的形式
     *
     * @param date 生辰日期, 默认格式为 "yyyy-MM-dd-HH", 即 yyyy为年 (范围1900~2099), MM为月, dd为日, HH为时（默认是24小时计数）
     * @return 返回一个Map集合, 键为 "year, month, day, hour", 值即为对应的干支
     */
    public static Map<String, String> dateFormat(String date) {

        // 先将字符串拆解成日期元素
        String[] dateSplit = date.split("-");

        Map<String, String> dateMap = new HashMap<>(4);

        // 获取年的干支, 并返回年的天干
        String yearHeavenlyStem = dateFormatYear(dateSplit[0], dateMap);
        // 通过年的天干, 获取月的干支
        dateFormatMonth(dateSplit[1], dateMap, yearHeavenlyStem);
        // 获取日的干支, 并返回日的天干
        String dayHeavenlyStem = dateFormatDay(dateSplit, dateMap);
        // 通过日的天干, 获取时的干支
        dateFormatHour(dateSplit[3], dateMap, dayHeavenlyStem);

        return dateMap;
    }

    /**
     * 将具体年份转化为年的干支
     *
     * @param year 年份
     */
    private static String dateFormatYear(String year, Map<String, String> map) {
        int i = Integer.parseInt(year);
        String heavenlyStem = DateConstant.HEAVENLY_STEMS[(i - 3) % 10];
        String earthlyBranch = DateConstant.EARTHLY_BRANCHES[(i - 3) % 12];
        map.put("year", heavenlyStem + earthlyBranch);
        return heavenlyStem;
    }

    /**
     * 将具体月份转化为月的干支
     *
     * @param month 月份
     */
    private static void dateFormatMonth(String month, Map<String, String> map, String yearHeavenlyStem) {
        int i = Integer.parseInt(month);
        switch (yearHeavenlyStem) {
            case "甲":
            case "己":
                map.put("month", DateConstant.HEAVENLY_STEMS_EARTHLY_BRANCHES_BY_MONTH[0][i - 1]);
                break;
            case "乙":
            case "庚":
                map.put("month", DateConstant.HEAVENLY_STEMS_EARTHLY_BRANCHES_BY_MONTH[1][i - 1]);
                break;
            case "丙":
            case "辛":
                map.put("month", DateConstant.HEAVENLY_STEMS_EARTHLY_BRANCHES_BY_MONTH[2][i - 1]);
                break;
            case "丁":
            case "壬":
                map.put("month", DateConstant.HEAVENLY_STEMS_EARTHLY_BRANCHES_BY_MONTH[3][i - 1]);
                break;
            case "戊":
            case "癸":
                map.put("month", DateConstant.HEAVENLY_STEMS_EARTHLY_BRANCHES_BY_MONTH[4][i - 1]);
                break;
            default:
                break;
        }
    }

    /**
     * 将具体日子转化为日的干支
     *
     * @param date 日期
     */
    private static String dateFormatDay(String[] date, Map<String, String> map) {
        int year = Integer.parseInt(date[0]);
        int month = Integer.parseInt(date[1]);
        int day = Integer.parseInt(date[2]);
        int sum = 0;
        if (year >= 1900 && year <= 1999) {
            sum = ((year % 100 + 3) * 5 + 55 + (year % 100 - 1) / 4) % 60;
        }
        if (year >= 2000 && year <= 2099) {
            sum = ((year % 100 + 7) * 5 + 15 + (year % 100 + 19) / 4) % 60;
        }
        for (int i = 1; i < month; i++) {
            if (i == 2) {
                if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                    sum += 29;
                } else {
                    sum += 28;
                }
            } else {
                if (i == 4 || i == 6 || i == 9 || i == 11) {
                    sum += 30;
                } else {
                    sum += 31;
                }
            }
        }
        sum += day;
        sum %= 60;
        String heavenlyStem = DateConstant.HEAVENLY_STEMS[sum % 10];
        String earthlyBranch = DateConstant.EARTHLY_BRANCHES[sum % 12];
        map.put("day", heavenlyStem + earthlyBranch);
        return heavenlyStem;
    }

    /**
     * 将具体时辰转化为时的干支
     *
     * @param hour 时辰
     */
    private static void dateFormatHour(String hour, Map<String, String> map, String dayHeavenlyStem) {
        int i = Integer.parseInt(hour);
        String heavenlyStem = null;
        String earthlyBranch = null;
        int index = 0;
        switch (i) {
            case 0:
            case 23:
                earthlyBranch = "子";
                index = 1;
                break;
            case 1:
            case 2:
                earthlyBranch = "丑";
                index = 2;
                break;
            case 3:
            case 4:
                earthlyBranch = "寅";
                index = 3;
                break;
            case 5:
            case 6:
                earthlyBranch = "卯";
                index = 4;
                break;
            case 7:
            case 8:
                earthlyBranch = "辰";
                index = 5;
                break;
            case 9:
            case 10:
                earthlyBranch = "巳";
                index = 6;
                break;
            case 11:
            case 12:
                earthlyBranch = "午";
                index = 7;
                break;
            case 13:
            case 14:
                earthlyBranch = "未";
                index = 8;
                break;
            case 15:
            case 16:
                earthlyBranch = "申";
                index = 9;
                break;
            case 17:
            case 18:
                earthlyBranch = "酉";
                index = 10;
                break;
            case 19:
            case 20:
                earthlyBranch = "戌";
                index = 11;
                break;
            case 21:
            case 22:
                earthlyBranch = "亥";
                index = 12;
                break;
            default:
                break;
        }
        switch (dayHeavenlyStem) {
            case "甲":
            case "己":
                heavenlyStem = DateConstant.HEAVENLY_STEMS[index % 10];
                break;
            case "乙":
            case "庚":
                heavenlyStem = DateConstant.HEAVENLY_STEMS[(index + 2) % 10];
                break;
            case "丙":
            case "辛":
                heavenlyStem = DateConstant.HEAVENLY_STEMS[(index + 4) % 10];
                break;
            case "丁":
            case "壬":
                heavenlyStem = DateConstant.HEAVENLY_STEMS[(index + 6) % 10];
                break;
            case "戊":
            case "癸":
                heavenlyStem = DateConstant.HEAVENLY_STEMS[(index + 8) % 10];
                break;
            default:
                break;
        }
        map.put("hour", heavenlyStem + earthlyBranch);
    }

}
